import threading
import socket
import json
from utils import *

tip_msg = """当前聊天室列表：
========================================
{}
----------------------------------------
【 回车\t-> 刷新列表 】
【 q\t-> 返回上一级 】
========================================
请输入要加入的聊天室索引并按回车："""

BUFFER_SIZE = 1024


class ChatScanner:

    def __init__(self):

        """
        接收当前所有局域网IP的8000端口的UDP广播消息，来获取所有聊天室。
        :return:
        """
        # 创建UDP socket
        self.udp_socket = None

        self.chatrooms = dict()

        # 是否接受中
        self.receiving = False

    def recv_broadcast_msg(self):
        self.receiving = True
        """
        接收UDP广播消息
        :param udp_socket: UDP socket
        :return:
        """
        while self.receiving:
            try:
                recv_data, ip_port = self.udp_socket.recvfrom(BUFFER_SIZE)
                recv_msg = decode_data(recv_data)
                # print(recv_msg)
                self.add_chatroom(recv_msg)
            except:
                pass

    def list(self):
        clear_console()
        self.init_socket()

        # 创建一个线程，用来接收UDP广播消息
        t = threading.Thread(target=self.recv_broadcast_msg)
        t.daemon = True
        t.start()

        print("正在获取聊天室列表，请稍等3...")
        time.sleep(1)
        clear_console()
        print("正在获取聊天室列表，请稍等2..")
        time.sleep(1)
        clear_console()
        print("正在获取聊天室列表，请稍等1.")
        time.sleep(0.5)
        clear_console()
        try:
            # 循环打印所有聊天室
            while True:
                # 调用函数清空控制台
                clear_console()

                values = list(self.chatrooms.values())
                # 按照聊天室名称排序
                values.sort(key=lambda x: x["name"])

                msg_lst = [
                    wrap_color(f" {index} -> {chatroom['name']}\t({chatroom['ip']}:{chatroom['port']})", Color.YELLOW)
                    for index, chatroom in enumerate(values)]
                print(tip_msg.format("\r\n".join(msg_lst) if len(msg_lst) != 0 else "暂无"))

                input_str = input("\r\n>")
                if input_str.isdigit():
                    index = int(input_str)
                    if 0 <= index < len(values):
                        chatroom = values[index]
                        return chatroom
                    else:
                        print(f"您输入的房间{index}不存在，请重新输入")
                        time.sleep(1)
                elif input_str == "q":
                    print("返回上一级")
                    break
                elif input_str == "":
                    print("刷新")
                    continue
                else:
                    print(f"输入无法识别【{input_str}】，请重新输入")
                    time.sleep(1)
        finally:
            self.receiving = False
            self.udp_socket.close()
            self.udp_socket = None

        return None

    def init_socket(self):
        self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.udp_socket.bind(("", 8000))
        # 设置socket为非阻塞
        # self.udp_socket.setblocking(False)

    def add_chatroom(self, recv_msg):
        """
        添加聊天室
        :param chatroom_dict:
        :return:
        """

        try:
            chatroom_dict = json.loads(recv_msg)
        except:
            # 格式不对就返回不理
            return

        # 如果不包含ip、port、name三个key，则不是聊天室，不添加
        if not all([key in chatroom_dict for key in ["ip", "port", "name"]]):
            return

        ip = chatroom_dict["ip"]
        port = chatroom_dict["port"]
        name = chatroom_dict["name"].strip()
        if name == "":
            name = f"匿名聊天室 {ip}:{port}"
        elif len(name) > 20:
            name = f"{name[:20]}..."

        chatroom_dict["name"] = name

        self.chatrooms[f"{ip}:{port}"] = chatroom_dict


if __name__ == '__main__':
    scanner = ChatScanner()
    print(scanner.list())
